/**
* @Auther:gy
* @Date:2021/7/21 9:57
 */

package aes

import (
	"encoding/base64"
	"errors"
	"github.com/forgoer/openssl"
)

/**
 * Aes CBC模式的base64加密
 */
/*
const PKCS5_PADDING = "PKCS5"
const PKCS7_PADDING = "PKCS7"
const ZEROS_PADDING = "ZEROS"
*/
func AesCBCEncryptBase64(src string, encoding *base64.Encoding, padding string, keyIvs ...string) (string, error) {
	key, iv := []byte{}, []byte{}
	if len(keyIvs) == 0 {
		return "", errors.New("未传入key")
	} else if len(keyIvs) == 1 {
		key = getKeyBytes(keyIvs[0])
		iv = key
	} else {
		key = getKeyBytes(keyIvs[0])
		iv = getKeyBytes(keyIvs[1])
	}
	cbcBt, e := openssl.AesCBCEncrypt([]byte(src), key, iv, padding)
	if e != nil {
		return "", e
	}
	return encoding.EncodeToString(cbcBt), nil
}

/**
 * Aes CBC模式的base64解密
 */
func AesCBCDecodeBase64(src string, encoding *base64.Encoding, padding string, keyIvs ...string) (string, error) {
	key, iv := []byte{}, []byte{}
	if len(keyIvs) == 0 {
		return "", errors.New("未传入key")
	} else if len(keyIvs) == 1 {
		key = getKeyBytes(keyIvs[0])
		iv = key
	} else {
		key = getKeyBytes(keyIvs[0])
		iv = getKeyBytes(keyIvs[1])
	}
	strCBC, e := encoding.DecodeString(src)
	if e != nil {
		return "", e
	}
	result, e1 := openssl.AesCBCDecrypt([]byte(strCBC), key, iv, padding)
	if e1 != nil {
		return "", e1
	}
	return string(result), nil
}

func getKeyBytes(key string) []byte {
	keyBytes := []byte(key)
	switch l := len(keyBytes); {
	case l < 16:
		keyBytes = append(keyBytes, make([]byte, 16-l)...)
	case l > 16:
		keyBytes = keyBytes[:16]
	}
	return keyBytes
}

/**
 * Aes ECB模式的base64加密
 */
func AesECBEncryptBase64(src string, encoding *base64.Encoding, key, padding string) (string, error) {
	keys := getKeyBytes(key)
	cbcBt, e := openssl.AesECBEncrypt([]byte(src), keys, padding)
	if e != nil {
		return "", e
	}
	return encoding.EncodeToString(cbcBt), nil
}

/**
 * Aes ECB模式的base64解密
 */
func AesECBDecodeBase64(src string, encoding *base64.Encoding, key, padding string) (string, error) {
	keys := getKeyBytes(key)
	strCBC, e := encoding.DecodeString(src)
	if e != nil {
		return "", e
	}
	result, e1 := openssl.AesECBDecrypt(strCBC, keys, padding)
	if e1 != nil {
		return "", e1
	}
	return string(result), nil
}
